<template>
  <div class="share-visit-container">
    <div v-if="loading" class="loading-container">
      <el-icon class="loading-icon"><Loading /></el-icon>
      <p>正在加载...</p>
    </div>

    <div v-else-if="error" class="error-container">
      <el-icon class="error-icon"><WarningFilled /></el-icon>
      <h2>分享链接无效</h2>
      <p>{{ error }}</p>
      <el-button type="primary" @click="goHome">返回首页</el-button>
    </div>

    <div v-else class="share-info-container">
      <!-- 密码验证对话框 -->
      <el-dialog
        v-model="passwordDialogVisible"
        title="请输入密码"
        width="400px"
      >
        <el-input
          v-model="password"
          type="password"
          placeholder="请输入分享密码"
          @keyup.enter="handleSubmitPassword"
        />
        <template #footer>
          <el-button @click="goHome">取消</el-button>
          <el-button type="primary" @click="handleSubmitPassword">确定</el-button>
        </template>
      </el-dialog>

      <!-- 分享内容 -->
      <div class="share-header">
        <h1>{{ shareInfo.shareName }}</h1>
        <div class="share-meta">
          <el-tag :type="shareInfo.shareType === 'file' ? 'primary' : 'success'">
            {{ shareInfo.shareType === 'file' ? '文件' : '文件夹' }}
          </el-tag>
          <span class="meta-item">
            <el-icon><User /></el-icon>
            资源名称：{{ shareInfo.resourceName }}
          </span>
        </div>
      </div>

      <div class="share-actions">
        <el-button
          v-if="shareInfo.allowDownload"
          type="primary"
          size="large"
          @click="handleDownload"
        >
          <el-icon><Download /></el-icon>
          下载
        </el-button>
        <el-button
          v-if="shareInfo.allowPreview"
          type="success"
          size="large"
          @click="handlePreview"
        >
          <el-icon><View /></el-icon>
          预览
        </el-button>
      </div>

      <div class="share-details">
        <el-descriptions :column="1" border>
          <el-descriptions-item label="访问次数">{{ shareInfo.accessCount || 0 }}</el-descriptions-item>
          <el-descriptions-item label="下载次数">{{ shareInfo.downloadCount || 0 }}</el-descriptions-item>
          <el-descriptions-item label="创建时间">{{ shareInfo.createTime }}</el-descriptions-item>
          <el-descriptions-item label="过期时间">
            <span v-if="shareInfo.isPermanent">永久有效</span>
            <span v-else>{{ shareInfo.expireTime || '-' }}</span>
          </el-descriptions-item>
        </el-descriptions>
      </div>
    </div>

    <!-- 文件预览对话框 -->
    <el-dialog
      v-model="previewDialogVisible"
      title="文件预览"
      width="80%"
      :close-on-click-modal="false"
      @close="handlePreviewClose"
    >
      <div v-if="previewFile" class="preview-container">
        <div class="preview-header">
          <h3>{{ previewFile.originalName }}</h3>
          <div class="preview-actions">
            <el-button @click="handlePreviewDownload" :icon="Download">
              下载
            </el-button>
          </div>
        </div>
        
        <div class="preview-content">
          <div v-if="previewFile" class="preview-area">
            <!-- 使用iframe直接显示文件 -->
            <iframe
              v-if="previewFile.previewUrl"
              :src="getFullPreviewUrl(previewFile.previewUrl)"
              class="preview-iframe"
              @load="handleIframeLoad"
              @error="handleIframeError"
            />
            
            <!-- 如果没有预览URL，显示不支持预览 -->
            <div v-if="!previewFile.previewUrl" class="preview-unsupported">
              <el-icon class="unsupported-icon">
                <Document />
              </el-icon>
              <p>此文件类型暂不支持在线预览</p>
              <p class="tip">请下载文件后使用本地软件打开</p>
              <el-button type="primary" @click="handlePreviewDownload">
                下载文件
              </el-button>
            </div>
          </div>
        </div>
      </div>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch, computed } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { ElMessage } from 'element-plus'
import { Loading, WarningFilled, Download, View, User, Document } from '@element-plus/icons-vue'
import { shareApi, fileApi } from '@/api/cd'
import type { CdShareVo, CdFileVo } from '@/types/cd'
import request from '@/utils/request'

const route = useRoute()
const router = useRouter()

const loading = ref(true)
const error = ref('')
const passwordDialogVisible = ref(false)
const password = ref('')
const shareInfo = ref<CdShareVo | null>(null)

// 预览相关状态
const previewDialogVisible = ref(false)
const previewFile = ref<CdFileVo | null>(null)
const imageUrl = ref<string>('')
const textContent = ref<string>('')

onMounted(() => {
  loadShareInfo()
})

const loadShareInfo = async () => {
  loading.value = true
  error.value = ''
  
  try {
    const shareCode = route.params.code as string
    if (!shareCode) {
      error.value = '分享码不能为空'
      loading.value = false
      return
    }

    const response = await shareApi.getInfo(shareCode)
    
    if (response.code === 200) {
      shareInfo.value = response.data
      
      // 检查是否需要密码
      if (shareInfo.value.accessLevel === 'password') {
        // 如果有缓存密码，直接验证
        const cachedPassword = sessionStorage.getItem(`share_password_${shareCode}`)
        if (cachedPassword) {
          await validatePassword(shareCode, cachedPassword)
        } else {
          passwordDialogVisible.value = true
        }
      } else if (shareInfo.value.accessLevel === 'restricted') {
        error.value = '该分享链接需要特定权限，请联系分享者'
      }
    } else {
      error.value = response.message || '获取分享信息失败'
    }
  } catch (err: any) {
    console.error('加载分享信息失败:', err)
    error.value = err.message || '获取分享信息失败'
  } finally {
    loading.value = false
  }
}

const validatePassword = async (shareCode: string, pwd: string) => {
  try {
    const response = await shareApi.validatePassword(shareCode, pwd)
    
    if (response.code === 200 && response.data) {
      // 密码验证成功，缓存密码
      sessionStorage.setItem(`share_password_${shareCode}`, pwd)
      passwordDialogVisible.value = false
      password.value = ''
    } else {
      ElMessage.error('密码错误')
    }
  } catch (err: any) {
    console.error('验证密码失败:', err)
    ElMessage.error(err.message || '验证密码失败')
  }
}

const handleSubmitPassword = async () => {
  if (!password.value) {
    ElMessage.warning('请输入密码')
    return
  }

  if (shareInfo.value) {
    await validatePassword(shareInfo.value.shareCode, password.value)
  }
}

// 判断是否为文本文件
const isTextFile = (filename: string): boolean => {
  const textExtensions = ['.txt', '.text', '.md', '.log', '.json', '.xml', '.html', '.css', '.js', '.vue', '.ts']
  const ext = filename.substring(filename.lastIndexOf('.')).toLowerCase()
  return textExtensions.includes(ext)
}

// 判断是否为Office文件
const isOfficeFile = (filename: string): boolean => {
  const officeExtensions = ['.doc', '.docx', '.xls', '.xlsx', '.ppt', '.pptx']
  const ext = filename.substring(filename.lastIndexOf('.')).toLowerCase()
  return officeExtensions.includes(ext)
}

// 获取PDF预览URL
const getPdfPreviewUrl = (file: CdFileVo): string => {
  const url = file.previewUrl || ''
  return url
}

// 获取Office预览URL
const getOfficePreviewUrl = (file: CdFileVo): string => {
  const shareCode = route.params.code as string
  const previewUrl = `/cd/share/preview/${shareCode}`
  return previewUrl
}

// 获取视频预览URL
const getVideoPreviewUrl = (file: CdFileVo): string => {
  const url = file.previewUrl || ''
  return url
}

// 获取音频预览URL
const getAudioPreviewUrl = (file: CdFileVo): string => {
  const url = file.previewUrl || ''
  return url
}

const handleDownload = async () => {
  if (!shareInfo.value) return
  
  if (shareInfo.value.shareType === 'file') {
    try {
      // 使用分享下载接口，参考预览对话框的下载方式
      const shareCode = route.params.code as string
      const downloadUrl = `/cd/share/download/${shareCode}`
      
      // 使用 request 获取 blob 数据
      const blob = await request({
        url: downloadUrl,
        method: 'get',
        responseType: 'blob'
      }) as any as Blob
      
      // 处理文件下载
      const url = window.URL.createObjectURL(blob)
      const link = document.createElement('a')
      link.href = url
      link.download = shareInfo.value.resourceName || 'download'
      document.body.appendChild(link)
      link.click()
      document.body.removeChild(link)
      window.URL.revokeObjectURL(url)
      
      ElMessage.success('文件下载成功')
    } catch (error) {
      console.error('下载文件失败:', error)
      ElMessage.error('下载文件失败')
    }
  } else {
    ElMessage.info('文件夹下载功能开发中...')
  }
}

const handlePreview = async () => {
  if (!shareInfo.value || shareInfo.value.shareType !== 'file') return
  
  try {
    // 使用分享接口获取文件信息
    const shareCode = route.params.code as string
    const fileInfoUrl = `/cd/share/file-info/${shareCode}`
    
    const fileResponse = await request({
      url: fileInfoUrl,
      method: 'get'
    }) as any
    
    if (fileResponse.code === 200) {
      const file = fileResponse.data
      console.log('获取到的文件信息:', file)
      console.log('预览URL:', file.previewUrl)
      previewFile.value = file
      previewDialogVisible.value = true
    }
  } catch (error) {
    console.error('预览文件失败:', error)
    ElMessage.error('预览文件失败')
  }
}

const handlePreviewDownload = async () => {
  if (!previewFile.value) return
  
  try {
    // 使用分享下载接口，参考预览对话框的下载方式
    const shareCode = route.params.code as string
    const downloadUrl = `/cd/share/download/${shareCode}`
    
    // 使用 request 获取 blob 数据
    const blob = await request({
      url: downloadUrl,
      method: 'get',
      responseType: 'blob'
    }) as any as Blob
    
    // 处理文件下载
    const url = window.URL.createObjectURL(blob)
    const link = document.createElement('a')
    link.href = url
    link.download = previewFile.value.originalName || 'download'
    document.body.appendChild(link)
    link.click()
    document.body.removeChild(link)
    window.URL.revokeObjectURL(url)
    
    ElMessage.success('文件下载成功')
  } catch (error) {
    console.error('下载文件失败:', error)
    ElMessage.error('下载文件失败')
  }
}

const handlePreviewClose = () => {
  previewDialogVisible.value = false
  previewFile.value = null
  if (imageUrl.value) {
    URL.revokeObjectURL(imageUrl.value)
    imageUrl.value = ''
  }
  textContent.value = ''
}

const handleIframeLoad = () => {
  console.log('iframe加载完成')
  console.log('iframe src:', previewFile.value?.previewUrl)
}

const handleIframeError = () => {
  console.error('iframe加载失败')
  console.error('iframe src:', previewFile.value?.previewUrl)
  ElMessage.error('文件预览失败')
}

const getFullPreviewUrl = (previewUrl: string) => {
  const basePath = import.meta.env.VITE_APP_BASE_API || '/dev-api'
  const fullUrl = `${basePath}${previewUrl}`
  console.log('完整预览URL:', fullUrl)
  return fullUrl
}

const goHome = () => {
  router.push('/')
}
</script>

<style scoped lang="scss">
.share-visit-container {
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background-color: var(--el-bg-color-page);
}

.loading-container,
.error-container,
.share-info-container {
  background: white;
  border-radius: 8px;
  padding: 48px;
  box-shadow: var(--el-box-shadow);
  text-align: center;
  max-width: 600px;
  width: 100%;
}

.loading-container {
  .loading-icon {
    font-size: 48px;
    color: var(--el-color-primary);
    margin-bottom: 16px;
    animation: rotate 1s linear infinite;
  }
}

.error-container {
  .error-icon {
    font-size: 64px;
    color: var(--el-color-danger);
    margin-bottom: 16px;
  }

  h2 {
    margin: 16px 0;
    color: var(--el-text-color-primary);
  }

  p {
    color: var(--el-text-color-regular);
    margin-bottom: 24px;
  }
}

.share-info-container {
  text-align: left;

  .share-header {
    margin-bottom: 24px;
    padding-bottom: 24px;
    border-bottom: 1px solid var(--el-border-color-light);

    h1 {
      margin: 0 0 16px 0;
      font-size: 24px;
      color: var(--el-text-color-primary);
    }

    .share-meta {
      display: flex;
      align-items: center;
      gap: 16px;
      color: var(--el-text-color-secondary);
      font-size: 14px;

      .meta-item {
        display: flex;
        align-items: center;
        gap: 4px;

        .el-icon {
          font-size: 16px;
        }
      }
    }
  }

  .share-actions {
    display: flex;
    gap: 12px;
    margin-bottom: 24px;
  }

  .share-details {
    margin-top: 24px;
  }
}

@keyframes rotate {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}

/* 预览对话框样式 */
.preview-container {
  height: 70vh;
  display: flex;
  flex-direction: column;
}

.preview-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  padding-bottom: 16px;
  border-bottom: 1px solid #e4e7ed;
  
  h3 {
    margin: 0;
    font-size: 18px;
    font-weight: 500;
  }
  
  .preview-actions {
    display: flex;
    gap: 8px;
  }
}

.preview-content {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  margin-top: 16px;
}

.preview-area {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.preview-image {
  max-width: 100%;
  max-height: 100%;
  object-fit: contain;
}

.preview-iframe {
  width: 100%;
  height: 100%;
  border: none;
}

.preview-text {
  width: 100%;
  height: 100%;
  overflow: auto;
  padding: 16px;
  background: #f5f5f5;
  border-radius: 4px;
  
  .text-content {
    margin: 0;
    white-space: pre-wrap;
    word-wrap: break-word;
    font-family: 'Courier New', monospace;
    font-size: 14px;
    line-height: 1.5;
  }
}

.preview-video {
  max-width: 100%;
  max-height: 100%;
}

.preview-audio {
  width: 100%;
  max-width: 500px;
}

.preview-unsupported {
  text-align: center;
  padding: 40px;
  
  .unsupported-icon {
    font-size: 48px;
    color: #909399;
    margin-bottom: 16px;
  }
  
  p {
    margin: 8px 0;
    color: #606266;
  }
  
  .tip {
    font-size: 12px;
    color: #909399;
  }
}

.loading {
  text-align: center;
  padding: 40px;
  
  .el-icon {
    font-size: 32px;
    margin-bottom: 16px;
  }
  
  p {
    margin: 0;
    color: #606266;
  }
}
</style>

